#include "RecvDCSBC.h"

//************************************
// Method:    	TimeOut_Deal			上位离线处理程序
// Programmer:  lww
// Time:		2019/1/9
// Returns:   	void
//************************************
void TimeOut_Deal()
{
	//< 接收上位广播信息超时
	//< 下位停止所有的广播，置所有广播的标志为0

	//< SAMA页调试广播标志位清零
	//memset(SAMA_PageBCFlag, 0, sizeof(SAMA_PageBCFlag));
	//< SAMA参数广播标志位清零
	BCSamaPara_Set.Flg = false;
	BCSamaPara_Set.Count = 0;
	//< IO点（数据库）广播标志清零
	BCIODataFlg = false;
	printf("Recv DCSBC Time out, Stop every BC\r\n");
}


//************************************
// Method:    	DCS_BCPACK_ANA			DCS广播数据包解析程序
// Programmer:  lww
// Time:		2019/2/16
// Returns:   	bool					true：成功；false：失败
// Parameter: 	short Head				报头
// Parameter: 	short Tail				报尾
// Parameter: 	void * Data				数据区头指针
//************************************
bool DCS_BCPACK_ANA(short Head,short Tail, void* Data)
{
#define MEMREAD1(var)	MEMREAD(var, Data)
#define WRONG_DEAL	{\
printf("Recv DCS BC PACK Wrong!\r\n");\
return false;\
}

	int _iLen = 0;
	short tmp_short;
	short ptr_off;
	int DCS_Addr = 0;

	//< 接收到上位广播的信息，进行解包操作
	//< 报头
	MEMREAD1(tmp_short);
	if (tmp_short != Head)
		WRONG_DEAL;

	//< 读出当前指针到报尾的指针的距离，校验报尾
	MEMREAD1(ptr_off);
	memcpy(&tmp_short, (char*)(Data) + ptr_off, sizeof(tmp_short));
	if (tmp_short != Tail)
		WRONG_DEAL;

	//< 读出上位的IP地址
	MEMREAD1(DCS_Addr);
//	printf("DCS_Addr = %d\r\n", DCS_Addr);

	return true;

#undef WRONG_DEAL
#undef MEMREAD1
}


//************************************
// Method:    	tRecvDCSBC				接收DCS广播线程
// Programmer:  lww
// Time:		2019/1/9
// Returns:   	void *
// Parameter: 	void * arg
//************************************
void *tRecvDCSBC(void* arg)
{
#define PACK_MAXNUM	256

	int sock;
	short Head = 7563;				//< 报头
	short Tail = 1281;				//< 报尾
	char Data2Recv[PACK_MAXNUM];	//< 存放数据包的数组
	struct timespec time;
	timer_t Test_DCS_TimeOut_Timer;
	const int Len = sizeof(Head) + sizeof(Tail) + sizeof(short) + sizeof(int);

	printf("the Kernel_%s is %d\r\n", "tRecvDCSBC_ID", syscall(SYS_gettid));			//< duan20200610

	//< 初始化UDP设置
	if (false == UDP_Init(&sock, RECVDCSBC_PORT, 0, 0, UDP_RECV_STATUS, nullptr)) { return 0; }

	//< 设置检测周期
	MS2TimeSpec(&time, TEST_DCS_TIMEOUT_PERIOD);

	//< 开启定时中断
	Timer_Create(&Test_DCS_TimeOut_Timer, TestDCSTimeOutSIG, &time); //此处的信号量是在定时器中断里进行的处理，在下面循环里为等待其释放
	while (1)
	{
		memset(Data2Recv, 0, sizeof(Data2Recv));
		//< 接收数据
		if (-1 == UDP_Recv_Fixed_Bytes(&sock, Data2Recv, Len))
			continue;

		DCS_TimeOut_Count = 0;
		//< IO点（数据库）广播标志置1
		BCIODataFlg = true;
		DCS_BCPACK_ANA(Head, Tail, Data2Recv);
	}
	close(sock);//< 断开连接

#undef PACK_MAXNUM
}
